package com.tanhua.backmanage.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.backmanage.enums.AgeRangeEnum;
import com.tanhua.backmanage.enums.IndustryEnum;
import com.tanhua.backmanage.vo.DistributionVo;
import com.tanhua.backmanage.vo.SummaryVo;
import com.tanhua.common.enums.SexEnum;
import com.tanhua.common.mapper.UserInfoMapper;
import com.tanhua.common.mapper.UserMapper;
import com.tanhua.common.pojo.User;
import com.tanhua.common.pojo.UserInfo;
import com.tanhua.dubbo.server.api.Users_xuApi;
import com.tanhua.dubbo.server.vo.DateNumberVo;
import com.tanhua.dubbo.server.vo.UsersVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class UserService_xu {
    @Autowired
    private UserMapper userMapper;

    @Reference
    private Users_xuApi users_xuApi;

    @Autowired
    private UserInfoMapper userInfoMapper;

    public SummaryVo summary() {

        SummaryVo summaryVo = new SummaryVo();

        //1.累计用户
        QueryWrapper<User> wrapper = new QueryWrapper();
        List<User> users = this.userMapper.selectList(wrapper);
        if (CollUtil.isNotEmpty(users)) {
            summaryVo.setCumulativeUsers(users.size());
        }

        //2.过去30天活跃用户
       // Integer queryActiveUserLastMonth = this.users_xuApi.queryActiveUserLastMonth();
       /* if(ObjectUtil.isNotEmpty(queryActiveUserLastMonth)){
            summaryVo.setActivePassMonth(queryActiveUserLastMonth);
        }*/
        summaryVo.setActivePassMonth(10);



        //3.过去7天活跃用户
        /*Integer queryActiveUserLastWeek = this.users_xuApi.queryActiveUserLastWeek();
        if(ObjectUtil.isNotEmpty(queryActiveUserLastWeek)){
            summaryVo.setActivePassMonth(queryActiveUserLastWeek);
        }*/
        summaryVo.setActivePassWeek(20);
        //4.今日新增用户
        QueryWrapper<UserInfo> wrapper4 = new QueryWrapper<>();
        //当前时间
        Date date = DateUtil.date();
        //当天0点
        DateTime dateTime = DateUtil.beginOfDay(date);
        wrapper4.between("created", dateTime, date);
        List<UserInfo> users4 = this.userInfoMapper.selectList(wrapper4);
        if (CollUtil.isNotEmpty(users4)) {
            summaryVo.setNewUsersToday(users4.size());
        }

        //5.今日新增用户涨跌率，单位百分数，正数为涨，负数为跌
        QueryWrapper<User> wrapper5 = new QueryWrapper<>();
        Date yesterDay = DateUtil.date();
        DateTime beginOfDay = DateUtil.beginOfDay(yesterDay);
        DateTime endOfDay = DateUtil.endOfDay(yesterDay);
        wrapper5.between("created", beginOfDay, endOfDay);
        List<User> users5 = this.userMapper.selectList(wrapper5);

        Integer ratio = this.ratio(users4.size(), users5.size());
        summaryVo.setNewUsersTodayRate(ratio);


        //6.今日登录次数
        Long count = this.users_xuApi.loginTimesToday();
        System.out.println(count);
        if(ObjectUtil.isNotEmpty(count)){
            summaryVo.setLoginTimesToday(Integer.parseInt(String.valueOf(count)));
        }
        //7.今日登录次数涨跌率，单位百分数，正数为涨，负数为跌
       /*Long rate = this.users_xuApi.queryLoginCountRate();
        summaryVo.setActivePassMonth(Integer.parseInt(String.valueOf(rate)));*/
       summaryVo.setActivePassMonth(78);

        //8.今日活跃用户;
        /*Integer integer = this.users_xuApi.activeUsersToday();
        if(ObjectUtil.isNotEmpty(integer)){
            summaryVo.setActivePassMonth(integer);
        }*/
        summaryVo.setActiveUsersToday(20);
        //9.今日活跃用户涨跌率，单位百分数，正数为涨，负数为跌
        summaryVo.setActiveUsersTodayRate(16);
        //10.过去7天平均日使用时长，单位秒
        summaryVo.setUseTimePassWeek(15);
        //11.昨日活跃用户
        summaryVo.setActiveUsersYesterday(18);
        //12.昨日活跃用户涨跌率，单位百分数，正数为涨，负数为跌
        summaryVo.setActiveUsersYesterdayRate(22);
        return summaryVo;
    }

    /**
     * 计算涨跌率:涨跌值／昨收盘＊100％
     *
     * @param newUsersToday  今日新增人数
     * @param lastUsersToday 昨日新增人数
     * @return
     */
    private Integer ratio(Integer newUsersToday, Integer lastUsersToday) {
        if (newUsersToday == 0 && lastUsersToday == 0) {
            return 0;
        } else if (newUsersToday == 0) {
            return -(lastUsersToday) * 100;
        } else if (lastUsersToday == 0) {
            return -(newUsersToday) * 100;
        } else {
            return (newUsersToday - lastUsersToday) / lastUsersToday * 100;
        }
    }


    /**
     * 新增、活跃用户、次日留存率
     *
     * @param sd   开始时间
     * @param ed   结束时间
     * @param type 101 新增 102 活跃用户 103 次日留存率
     * @return
     */
    public UsersVo users(long sd, long ed, String type) {
        //当前的开始,结束时间
        DateTime startTime = DateUtil.date(sd);
        DateTime endTime = DateUtil.date(ed);
      /*  DateTime startTime = DateUtil.parse(sd);
        DateTime endTime = DateUtil.parse(ed);*/

        //去年的开始,结束时间
        DateTime lastStartTime = DateUtil.offsetMonth(startTime, -12);
        DateTime lastEndTime = DateUtil.offsetMonth(endTime, -12);

        UsersVo usersVo = new UsersVo();

        switch (type) {
            //新增用户
            case "101":
                usersVo = getAddingUserData(startTime, endTime, lastStartTime, lastEndTime);
                break;
            //活跃用户
            case "102":
                DateNumberVo dateNumberVo = new DateNumberVo("2021-09-12", 13);
                DateNumberVo dateNumberVo2 = new DateNumberVo("2021-09-13", 16);
                DateNumberVo dateNumberVo3 = new DateNumberVo("2021-09-14", 25);
                DateNumberVo dateNumberVo4 = new DateNumberVo("2021-09-15", 45);
                DateNumberVo dateNumberVo5 = new DateNumberVo("2021-09-16", 78);
                DateNumberVo dateNumberVo6 = new DateNumberVo("2021-09-17", 123);
                DateNumberVo dateNumberVo7 = new DateNumberVo("2021-09-18", 167);
                List<DateNumberVo> thisYear  = new ArrayList<>();
                thisYear.add(dateNumberVo);
                thisYear.add(dateNumberVo2);
                thisYear.add(dateNumberVo3);
                thisYear.add(dateNumberVo4);
                thisYear.add(dateNumberVo5);
                thisYear.add(dateNumberVo6);
                thisYear.add(dateNumberVo7);
                usersVo.setThisYear(thisYear);
                break;
            //次日留存率
            case "103":
                DateNumberVo dateNumberVo8 = new DateNumberVo("2021-09-12", 5);
                DateNumberVo dateNumberVo9 = new DateNumberVo("2021-09-13", 16);
                DateNumberVo dateNumberVo10 = new DateNumberVo("2021-09-14", 25);
                DateNumberVo dateNumberVo11 = new DateNumberVo("2021-09-15", 15);
                DateNumberVo dateNumberVo12 = new DateNumberVo("2021-09-16", 15);
                DateNumberVo dateNumberVo13 = new DateNumberVo("2021-09-17", 5);
                DateNumberVo dateNumberVo14 = new DateNumberVo("2021-09-18", 5);
                List<DateNumberVo> thisYear1  = new ArrayList<>();
                thisYear1.add(dateNumberVo8);
                thisYear1.add(dateNumberVo9);
                thisYear1.add(dateNumberVo10);
                thisYear1.add(dateNumberVo11);
                thisYear1.add(dateNumberVo12);
                thisYear1.add(dateNumberVo13);
                thisYear1.add(dateNumberVo14);
                usersVo.setThisYear(thisYear1);

                break;

            default:
                return null;
        }

        return usersVo;
    }



    private UsersVo getAddingUserData(DateTime startTime, DateTime endTime, DateTime lastStartTime, DateTime lastEndTime) {
        long betweenDay = DateUtil.between(startTime, endTime, DateUnit.DAY);
        //当前时间
        String today = DateUtil.today();
        //获取结束时间
        String format = DateUtil.format(endTime, "yyyy-MM-dd");
        if (betweenDay == 7 && StrUtil.equals(today, format)) {
            return this.getWeek(startTime, endTime, lastStartTime, lastEndTime);
        } else if (betweenDay == 30 && StrUtil.equals(today, format)) {
            return this.getMonth(startTime, endTime, lastStartTime, lastEndTime);
        } else {
            return this.getCustomTime(startTime, endTime, lastStartTime, lastEndTime);
        }
    }



    /**
     * 本周新增用户数据
     *
     * @param startTime     //当前的开始时间
     * @param endTime       //当前的结束时间
     * @param lastStartTime //一年前的开始时间
     * @param lastEndTime   //一年前的开始时间
     * @return
     */
    public UsersVo getWeek(Date startTime, Date endTime, Date lastStartTime, Date lastEndTime) {
        //创建返回对象
        UsersVo usersVo = new UsersVo();

        //今年新增用户数据
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.between("created", startTime, endTime);
        List<User> userList = this.userMapper.selectList(wrapper);

        List<DateNumberVo> thisYear = new ArrayList<>();
        for (int i = 1; i <= 8; i++) {
            DateNumberVo dateNumberVo = new DateNumberVo();
            Integer amount = 0;
            for (User user : userList) {

                String dd1 = DateUtil.format(user.getCreated(), "dd");
                String dd2 = DateUtil.format(startTime, "dd");
                if (StrUtil.equals(dd1,dd2)) {
                    amount++;
                }
            }
            String format = DateUtil.format(startTime, "dd");
            dateNumberVo.setTitle(format);
            dateNumberVo.setAmount(amount);
            thisYear.add(dateNumberVo);
            startTime = DateUtil.offsetDay(startTime, 1);
        }
        usersVo.setThisYear(thisYear);

        //去年新增用户数据
        QueryWrapper<User> lastWrapper = new QueryWrapper<>();
        lastWrapper.between("created", lastStartTime, lastEndTime);
        List<User> lastUserList = this.userMapper.selectList(lastWrapper);

        //按照一周7天遍历查询,如果日期和User创建日期相同 amount+1
        List<DateNumberVo> lastYear = new ArrayList<>();
        for (int i = 1; i <= 8; i++) {
            DateNumberVo dateNumberVo = new DateNumberVo();
            Integer amount = 0;
            for (User user : lastUserList) {

                String dd1 = DateUtil.format(user.getCreated(), "dd");
                String dd2 = DateUtil.format(lastStartTime, "dd");
                if (StrUtil.equals(dd1,dd2)) {
                    amount++;
                }
            }
            String format = DateUtil.format(lastStartTime, "dd");
            dateNumberVo.setTitle(format);
            dateNumberVo.setAmount(amount);
            lastYear.add(dateNumberVo);
            lastStartTime = DateUtil.offsetDay(lastStartTime, 1);
        }
        usersVo.setLastYear(lastYear);

        return usersVo;
    }

    /**
     * 本月新增用户数据
     *
     * @param startTime     //当前的开始时间
     * @param endTime       //当前的结束时间
     * @param lastStartTime //一年前的开始时间
     * @param lastEndTime   //一年前的开始时间
     * @return
     */
    public UsersVo getMonth(Date startTime, Date endTime, Date lastStartTime, Date lastEndTime) {
        //创建返回对象
        UsersVo usersVo = new UsersVo();

        //今年新增用户数据
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.between("created", startTime, endTime);
        List<User> userList = this.userMapper.selectList(wrapper);

        //按照一月30天遍历查询,如果月份日期和User创建的月份日期相同 amount+1
        List<DateNumberVo> thisYear = new ArrayList<>();
        for (int i = 1; i <= 31; i++) {
            DateNumberVo dateNumberVo = new DateNumberVo();
            Integer amount = 0;
            for (User user : userList) {
                String dd1 = DateUtil.format(user.getCreated(), "MM-dd");
                String dd2 = DateUtil.format(startTime, "MM-dd");
                if (StrUtil.equals(dd1, dd2)) {
                    amount++;
                }
            }
            String format = DateUtil.format(startTime, "MM-dd");
            dateNumberVo.setTitle(format);
            dateNumberVo.setAmount(amount);
            thisYear.add(dateNumberVo);
            startTime = DateUtil.offsetDay(startTime, 1);
        }
        usersVo.setThisYear(thisYear);

        //去年新增用户数据
        QueryWrapper<User> lastWrapper = new QueryWrapper<>();
        lastWrapper.between("created", lastStartTime, lastEndTime);
        List<User> lastUserList = this.userMapper.selectList(lastWrapper);
        //按照一月30天遍历查询,如果月份日期和User创建的月份日期相同 amount+1
        List<DateNumberVo> lastYear = new ArrayList<>();
        for (int i = 1; i <= 31; i++) {
            DateNumberVo dateNumberVo = new DateNumberVo();
            Integer amount = 0;
            for (User user : lastUserList) {
                String dd1 = DateUtil.format(user.getCreated(), "MM-dd");
                String dd2 = DateUtil.format(lastStartTime, "MM-dd");
                if (StrUtil.equals(dd1, dd2)) {
                    amount++;
                }
            }
            String format = DateUtil.format(lastStartTime, "MM-dd");
            dateNumberVo.setTitle(format);
            dateNumberVo.setAmount(amount);
            lastYear.add(dateNumberVo);
            lastStartTime = DateUtil.offsetDay(lastStartTime, 1);
        }
        usersVo.setLastYear(lastYear);

        return usersVo;
    }
        //今年的新增用户
        private UsersVo getCustomTime(DateTime startTime, DateTime endTime, DateTime lastStartTime, DateTime lastEndTime) {
        UsersVo usersVo = new UsersVo();
        DateNumberVo dateNumberVo = new DateNumberVo();
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.between("created", startTime, endTime);
        List<User> userList = this.userMapper.selectList(wrapper);

        ArrayList<DateNumberVo> thisYear = new ArrayList<>();
        for (int i = 1; i <= 12; i++) {
            Integer amount = 0;
            for (User user : userList) {
                int month = DateUtil.month(user.getCreated()) + 1;
                if (i == month) {
                    amount++;
                }
            }
            dateNumberVo.setTitle(i + "");
            dateNumberVo.setAmount(amount);
            thisYear.add(dateNumberVo);
        }
        usersVo.setThisYear(thisYear);

        //去年新增数据
        QueryWrapper<User> wrapper2 = new QueryWrapper<>();
        wrapper2.between("created", lastStartTime, lastEndTime);
        List<User> lastUserList = this.userMapper.selectList(wrapper2);
        ArrayList<DateNumberVo> lastYear = new ArrayList<>();
        for (int i = 1; i <= 12; i++) {
            Integer amount = 0;
            for (User user : lastUserList) {
                int month = DateUtil.month(user.getCreated()) + 1;
                if (i == month) {
                    amount++;
                }
            }
            dateNumberVo.setTitle(i + "月");
            dateNumberVo.setAmount(amount);
            lastYear.add(dateNumberVo);
        }

        usersVo.setLastYear(lastYear);
        return usersVo;
    }
//概要
    public DistributionVo distribution(long sd, long ed) {
        DistributionVo distributionVo = new DistributionVo();

        Date date = new Date(sd);
        Date date1 = new Date(ed);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String start = dateFormat.format(date);
        String end = dateFormat.format(date1);

        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.gt("created", start).lt("created", end);
        List<UserInfo> userInfos = userInfoMapper.selectList(queryWrapper);

        //年龄分布
        List<DateNumberVo> ageDistribution = new ArrayList<>();
        Integer size1 = userInfos.stream().filter(userInfo -> userInfo.getAge() >= 0 && userInfo.getAge() < 20).collect(Collectors.toList()).size();
        Integer size2 = userInfos.stream().filter(userInfo -> userInfo.getAge() >= 20 && userInfo.getAge() < 30).collect(Collectors.toList()).size();
        Integer size3 = userInfos.stream().filter(userInfo -> userInfo.getAge() >= 30 && userInfo.getAge() < 40).collect(Collectors.toList()).size();
        Integer size4 = userInfos.stream().filter(userInfo -> userInfo.getAge() >= 40 && userInfo.getAge() < 50).collect(Collectors.toList()).size();
        Integer size5 = userInfos.stream().filter(userInfo -> userInfo.getAge() >= 50 && userInfo.getAge() < 200).collect(Collectors.toList()).size();

        ageDistribution.add(new DateNumberVo(AgeRangeEnum.UNDER_TWENTY.getDesc(),size1));
        ageDistribution.add(new DateNumberVo(AgeRangeEnum.TWENTY.getDesc(), size2));
        ageDistribution.add(new DateNumberVo(AgeRangeEnum.THIRTY.getDesc(), size3));
        ageDistribution.add(new DateNumberVo(AgeRangeEnum.FORTY.getDesc(), size4));
        ageDistribution.add(new DateNumberVo(AgeRangeEnum.OVER_FIFTY.getDesc(), size5));

        //性别分布
        List<DateNumberVo> genderDistribution = new ArrayList<>();
        Integer countMan = userInfos.stream().filter(userInfo -> (userInfo.getSex()==SexEnum.MAN)).collect(Collectors.toList()).size();
        Integer countWoman = userInfos.size() - countMan;
        genderDistribution.add(new DateNumberVo("男性用户", countMan));
        genderDistribution.add(new DateNumberVo("女性用户", countWoman));

        //行业分布
        List<DateNumberVo> industryDistribution = new ArrayList<>();
        Integer computerCount = userInfos.stream().filter(userInfo -> userInfo.getIndustry().equals("计算机")).collect(Collectors.toList()).size();
        industryDistribution.add(new DateNumberVo(IndustryEnum.COMPUTER.getDesc(),computerCount));


        distributionVo.setAgeDistribution(ageDistribution);
        distributionVo.setAgeDistribution(genderDistribution);

        return distributionVo;
    }
}